// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PageBlobDriveInfo.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Data structure with information on a Page Blob mounted as a Drive on the current instance.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.IO;

namespace AzureContrib.WindowsAzure.StorageClient
{
	/// <summary>
	/// Data structure with information on a Page Blob mounted as a Drive on the current instance.
	/// </summary>
	public struct PageBlobDriveInfo : IEquatable<PageBlobDriveInfo>
	{
		private readonly DirectoryInfo rootPath;
		private readonly Uri pageBlobUri;
		private readonly IStorageCredentials storageCredentials;

		/// <summary>
		/// Initializes a new instance of the PageBlobDriveInfo struct.
		/// </summary>
		/// <param name="rootPath">The root path to the mounted resource.</param>
		/// <param name="pageBlobUri">The <see cref="Uri"/> to the mounted Page Blob.</param>
		/// <param name="storageCredentials">The <see cref="IStorageCredentials"/> used to access the Page Blob.</param>
		public PageBlobDriveInfo(DirectoryInfo rootPath, Uri pageBlobUri, IStorageCredentials storageCredentials)
			: this()
		{
			this.rootPath = rootPath;
			this.pageBlobUri = pageBlobUri;
			this.storageCredentials = storageCredentials;
		}

		/// <summary>
		/// Gets the root path to the mounted resource.
		/// </summary>
		public DirectoryInfo RootPath
		{
			get
			{
				return rootPath;
			}
		}

		/// <summary>
		/// Gets the <see cref="Uri"/> to the mounted Page Blob.
		/// </summary>
		public Uri PageBlobUri
		{
			get
			{
				return pageBlobUri;
			}
		}

		/// <summary>
		/// Gets the <see cref="IStorageCredentials"/> used to access the Page Blob.
		/// </summary>
		public IStorageCredentials StorageCredentials
		{
			get
			{
				return storageCredentials;
			}
		}

		/// <summary>
		/// Finds if two instances of <see cref="PageBlobDriveInfo"/> are equal.
		/// </summary>
		/// <param name="left">One of the two to compare.</param>
		/// <param name="right">The other one to compare.</param>
		/// <returns>True if the instances are equal.</returns>
		public static bool operator ==(PageBlobDriveInfo left, PageBlobDriveInfo right)
		{
			return left.Equals(right);
		}

		/// <summary>
		/// Finds if two instances of <see cref="PageBlobDriveInfo"/> are not equal.
		/// </summary>
		/// <param name="left">One of the two to compare.</param>
		/// <param name="right">The other one to compare.</param>
		/// <returns>True if the instances are not equal.</returns>
		public static bool operator !=(PageBlobDriveInfo left, PageBlobDriveInfo right)
		{
			return !left.Equals(right);
		}

		/// <summary>
		/// Indicates whether the current object is equal to another object of the same type.
		/// </summary>
		/// <returns>
		/// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
		/// </returns>
		/// <param name="other">An object to compare with this object.</param>
		public bool Equals(PageBlobDriveInfo other)
		{
			return Equals(other.rootPath, rootPath) && 
						 Equals(other.pageBlobUri, pageBlobUri) && 
						 Equals(other.storageCredentials, storageCredentials);
		}

		/// <summary>
		/// Indicates whether this instance and a specified object are equal.
		/// </summary>
		/// <returns>
		/// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
		/// </returns>
		/// <param name="obj">Another object to compare to. </param><filterpriority>2</filterpriority>
		public override bool Equals(object obj)
		{
			return ReferenceEquals(null, obj) && obj is PageBlobDriveInfo && Equals((PageBlobDriveInfo)obj);
		}

		/// <summary>
		/// Returns the hash code for this instance.
		/// </summary>
		/// <returns>
		/// A 32-bit signed integer that is the hash code for this instance.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked
			{
				var result = rootPath != null ? rootPath.GetHashCode() : 0;
				result = result ^ (pageBlobUri != null ? pageBlobUri.GetHashCode() : 0);
				result = result ^ (storageCredentials != null ? storageCredentials.GetHashCode() : 0);
				return result;
			}
		}
	}
}